Skip to content

Fix DDL bugs in schema, enums, indexes, and triggers tools - #7

Closed
bq011 wants to merge 1 commit into
HenkDz:mainfrom
bq011:fix/schema-enum-index-trigger-bugs
Closed

Fix DDL bugs in schema, enums, indexes, and triggers tools#7
bq011 wants to merge 1 commit into
HenkDz:mainfrom
bq011:fix/schema-enum-index-trigger-bugs

Conversation

@bq011

@bq011 bq011 commented Apr 25, 2026

Copy link
Copy Markdown

Summary

Five bugs uncovered by smoke-testing pg_manage_schema, pg_manage_indexes and pg_manage_triggers against PostgreSQL 15. All five reproduce on main and pass after this PR.

1. create_table / alter_table ignored the schema parameter

The Zod schema for the schema-management operations omitted schema, and the SQL builders hardcoded unqualified table names. Tables silently landed in public even when the caller asked for another schema. Fixed by adding schema to the input schema and qualifying identifiers as "schema"."table".

2. create_enum used $1 placeholders inside CREATE TYPE

PostgreSQL does not accept parameter placeholders in DDL — the server returned syntax error at or near "$1". Replaced with escaped string literals (single-quote doubling for safety).

3. create_enum with ifNotExists=true emitted CREATE TYPE IF NOT EXISTS

PostgreSQL has no IF NOT EXISTS clause for CREATE TYPE. Wrapped the statement in a DO block that checks pg_type/pg_namespace before EXECUTE-ing the create.

4. get_indexes / analyze_index_usage referenced non-existent columns

The queries selected tablename and indexname from pg_stat_user_indexes, but that view exposes relname and indexrelname. The result was column "tablename" does not exist. Aliased to psi.relname AS tablename / psi.indexrelname AS indexname and qualified the WHERE predicates with psi..

5. create_trigger mis-quoted schema-qualified function names

const qualifiedFunctionName = \"${functionName}"`turnedpublic.touch_updated_atinto the literal identifier"public.touch_updated_at", so PostgreSQL reported function "public.touch_updated_at" does not exist`. Now each dotted part is quoted independently, and bare names default to the trigger's own schema.

Test plan

  • npm install && npm run build clean
  • Re-ran each of the five failing scenarios in an isolated mcp_smoke schema against PostgreSQL 15.17 — all pass
  • Verified pg_stat_user_indexes query returns the expected row shape after creating an index
  • Verified CREATE TRIGGER ... EXECUTE FUNCTION "schema"."fn"() resolves the function correctly

Five bugs uncovered by smoke-testing pg_manage_schema, pg_manage_indexes
and pg_manage_triggers against PostgreSQL 15:

1. create_table / alter_table ignored the `schema` parameter and always
   wrote to public. Added schema to the input zod schema and qualified
   identifiers as "schema"."table".

2. create_enum used `$1` placeholders inside CREATE TYPE, which
   PostgreSQL rejects in DDL ("syntax error at or near $1"). Switched
   to escaped string literals.

3. create_enum with ifNotExists=true emitted `CREATE TYPE IF NOT EXISTS`,
   which PostgreSQL does not support. Wrapped the statement in a DO
   block that checks pg_type/pg_namespace before EXECUTE.

4. get_indexes / analyze_index_usage queried pg_stat_user_indexes using
   `tablename` and `indexname` columns that do not exist on that view
   (the actual columns are `relname` / `indexrelname`). Aliased them
   correctly and qualified WHERE clauses with `psi.`.

5. create_trigger wrapped the entire function name in a single pair of
   double quotes, so `public.touch_updated_at` became the literal
   identifier `"public.touch_updated_at"`. Quote each dotted part
   separately, and default bare names to the trigger's own schema.

Verified by re-running the failing scenarios against PostgreSQL 15.17
in an isolated schema.
@HenkDz

HenkDz commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Closing this stale/conflicting PR because the schema, enum, and trigger fixes were covered by the hardening work in #8, and the remaining pg_stat_user_indexes catalog-query fix has been applied directly on main in 366a98f. Thanks for the clear bug report and repro notes.

@HenkDz HenkDz closed this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants